package bugzillapreprocessor.view;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import bugzillapreprocessor.adaptor.DateAdaptor;
import bugzillapreprocessor.adaptor.PrinterAdapter;
import bugzillapreprocessor.model.Issue;

/**
 * The class which produces the issue-dependencies.txt file
 * 
 * @author c_haras
 */
class DependencyView implements Views {

	private final String filename = "issue-dependencies.txt";
	private ArrayList<Issue> issues;
	private Hashtable<String, ArrayList<String>> dependencyList;

	/**
	 * Constructor
	 */
	public DependencyView() {
		dependencyList = new Hashtable<String, ArrayList<String>>();
	}

	/**
	 * Process the issue objects for additional data and for printing
	 */
	public void processData(ArrayList<Issue> issues) {
		this.issues = issues;
		if (issues.size() > 0) {
			fillDependencyList();
			printToFile(convertToString());
		} else {
			printToFile("");
		}
	}

	/**
	 * Print the processed data to a file
	 * 
	 * @param msg
	 *            The data to print to file
	 */
	private void printToFile(String msg) {
		PrinterAdapter.print(filename, msg);
	}

	/**
	 * Convert the issue data to a string which will be output to file
	 * 
	 * @return The String representation of the data for all issues
	 */
	private String convertToString() {

		StringBuilder sb = new StringBuilder();
		String ls = System.getProperty("line.separator");
		int numberOfDependencies = 0;
		Iterator<Issue> it = issues.iterator();
		int issueCount = 0;

		while (it.hasNext()) {
			Issue i = (Issue) it.next();

			if ((i.getResolution().equalsIgnoreCase("Fixed") == false)
					|| (i.getIssueStatus().equalsIgnoreCase("Closed") == false))
				continue;

			String issueId = i.getIssueID();
			numberOfDependencies = getNumberOfDependencies(issueId);
			String deltaTs = i.getDelta_ts();
			String creationTs = i.getCreation_ts();

			sb.append("---------------------New Issue - Issue #")
					.append(++issueCount).append("---------------").append(ls);
			sb.append("Issue_ID: ").append(issueId).append(ls);
			sb.append("Issue_Type: ").append(i.getIssueType()).append(ls);
			sb.append("Resolution: ").append("Fixed").append(ls);
			sb.append("Issue_Status: ").append("closed").append(ls);
			sb.append("Delta_ts: ").append(deltaTs).append(ls);
			sb.append("Delta_ts_since: ").append(getDaysSince2001(deltaTs))
					.append(ls);
			sb.append("Creation_ts: ").append(creationTs).append(ls);
			sb.append("Creation_ts_since: ")
					.append(getDaysSince2001(creationTs)).append(ls);
			sb.append("Number_of_dependencies: ").append(numberOfDependencies)
					.append(ls);
			sb.append("Priority: ").append(i.getPriority()).append(ls);
			sb.append("Days_open: ").append(getDaysOpen(deltaTs, creationTs))
					.append(ls);
			sb.append(
					"-------------------------Issue Ended--------------------")
					.append(ls);
		}
		return sb.toString();
	}

	/**
	 * Get the number of days from the given date to 2001-01-01
	 * 
	 * @param date
	 *            The end date
	 * @return The number of days between date and 2001-01-01
	 */
	private long getDaysSince2001(String date) {
		return DateAdaptor.getDays(date, "2000-01-01 00:00:00");
	}

	/**
	 * Get the number of days from the given date1 to given date2
	 * 
	 * @param date1
	 *            From date
	 * @param date2
	 *            To date
	 * @return The number of day between date1 and date2
	 */
	private long getDaysOpen(String date1, String date2) {
		return DateAdaptor.getDays(date1, date2);
	}

	/**
	 * Count the number of dependencies for the issue with issueId
	 * 
	 * @param issueId
	 *            The id of the issue to count dependencies
	 * @return The number of dependencies
	 */
	private int getNumberOfDependencies(String issueId) {
		return this.dependencyList.get(issueId).size();
	}

	/**
	 * Loop over the issue objects and establish the number of dependencies per
	 * issue
	 */
	private void fillDependencyList() {
		Iterator<Issue> it = issues.iterator();
		while (it.hasNext()) {
			Issue i = (Issue) it.next();
			String issueId = i.getIssueID();

			ArrayList<String> dependsOnIssueIdList = i.getDependsOnIssueList();
			if (dependencyList.contains(issueId)) {
				dependencyList.get(issueId).addAll(dependsOnIssueIdList);
			} else {
				ArrayList<String> list = new ArrayList<String>();
				list.addAll(dependsOnIssueIdList);
				dependencyList.put(issueId, list);
			}
		}
	}
}
